package info.manxi;

import akka.actor.AbstractFSM;
import akka.japi.pf.UnitMatch;

import java.time.Duration;
import java.util.Arrays;
import java.util.LinkedList;

import static info.manxi.状态枚举.活动的;
import static info.manxi.状态枚举.闲置;
import static info.manxi.初始化数据.初始数据;

class Buncher extends AbstractFSM<状态枚举, 可接受数据> {
    {
        startWith(闲置, 初始数据);

        when(
                闲置,
                matchEvent(
                        设置目标事件.class,
                        初始化数据.class,
                        (setTarget, uninitialized) ->
                                stay().using(new 运行时数据(setTarget.getRef(), new LinkedList<>()))));

        onTransition(
                matchState(
                        活动的,
                        闲置,
                        () -> {
                            // reuse this matcher
                            final UnitMatch<可接受数据> m =
                                    UnitMatch.create(
                                            matchData(
                                                    运行时数据.class,
                                                    todo ->
                                                            todo.getTarget().tell(new Batch(todo.getQueue()), getSelf())));
                            m.match(stateData());
                        })
                        .state(
                                闲置,
                                活动的,
                                () -> {
                                    /* Do something here */
                                }));

        when(
                活动的,
                Duration.ofSeconds(1L),
                matchEvent(
                        Arrays.asList(清空事件.class, StateTimeout()),
                        运行时数据.class,
                        (event, todo) -> goTo(闲置).using(todo.copy(new LinkedList<>()))));

        whenUnhandled(
                matchEvent(
                        入队事件.class,
                        运行时数据.class,
                        (queue, todo) -> goTo(活动的).using(todo.addElement(queue.getObj())))
                        .anyEvent(
                                (event, state) -> {
                                    log().warning("未处理的事件 {} 对于状态 {}/{}", event, stateName(), state);
                                    return stay();
                                }));

        initialize();
    }
}